/**
 **************************************************************************************************************************
 * 
 **************************************************************************************************************************
 * @file RBSpatialComponent.h
 **************************************************************************************************************************/

#pragma once

#ifdef  HEADER_MSG
#pragma HEADER_MSG(RBSpatialComponent.h)
#endif


/**************************************************************************************************************************
 * Includes
 **************************************************************************************************************************/
#include "RBTransformSystem/RBTransformComponent.h"

/**************************************************************************************************************************
 * Forward declarations
 **************************************************************************************************************************/


/**************************************************************************************************************************
 * Classes
 **************************************************************************************************************************/
/**************************************************************************************************************************
 * Helper for all spatial objects (no virtual involved)
 **************************************************************************************************************************/
template<class TComponent>
class RBTSpatialComponent : public RBTComponent<TComponent>
{
public:
    static void                 Create              (RBEntityHandle entityHandle, RBTransformComponentHandle* xForms, RBTComponentHandle* pHandles, uint32 count);
    static RBTComponentHandle   Create              (RBEntityHandle entityHandle, RBTransformComponentHandle xForm = InvalidHandle);

    RBTransform&                WorldXForm          ()       { return RBTransformComponent::Get(m_xForm.Handle).WorldXForm(); }
    RBTransform&                LocalXForm          ()       { return RBTransformComponent::Get(m_xForm.Handle).LocalXForm(); }

    const RBTransform&          WorldXForm          () const { return RBTransformComponent::Get(m_xForm.Handle).WorldXForm(); }
    const RBTransform&          LocalXForm          () const { return RBTransformComponent::Get(m_xForm.Handle).LocalXForm(); }

    RBTransformComponentHandle  get_xform_handle    () const { return m_xForm; }

protected:
                                RBTSpatialComponent (RBEntityHandle entityHandle, RBTransformComponentHandle xForm);

    RBTransformComponentHandle m_xForm;

};

template<class TComponent>
RBTSpatialComponent<TComponent>::RBTSpatialComponent( RBEntityHandle entityHandle, RBTransformComponentHandle xForm )
: RBTComponent(entityHandle)
{
    m_xForm = (xForm != InvalidHandle)  ? xForm : RBTransformComponent::Create(entityHandle);
}


template<class TComponent>
void RBTSpatialComponent<TComponent>::Create( RBEntityHandle entityHandle, RBTransformComponentHandle* xForms, RBTComponentHandle* pHandles, uint32 count )
{
    for (uint32 ui=0; ui < count; ++ui)
    {
        pHandles[ui] = (RBTComponentHandle)stb_arr_len(Instances);
        stb_arr_push_obj(Instances, TComponent(entityHandle, xForms[ui]));
    }
}

template<class TComponent>
RBHandle<TComponent> RBTSpatialComponent<TComponent>::Create( RBEntityHandle entityHandle, RBTransformComponentHandle xForm )
{
    RBTComponentHandle cmpHandle;
    Create(entityHandle, &xForm, &cmpHandle, 1);
    return cmpHandle;
}
